﻿using Microsoft.BizTalk.BtsDbVersion;
using Microsoft.BizTalk.Tracing;
using Microsoft.BizTalk.Tracking;
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Globalization;
using System.Management;
using System.Runtime.InteropServices;
using System.Web;
using System.Windows.Forms;
using Bizspoke.BizTalk.Tracking;
using System.Collections.Generic;

namespace Bizspoke.BizTalk.Brma
{
    [CLSCompliant(false), ComVisible(true), Guid("124B0FB8-DF1E-46b0-97B1-FD698C35C497")]
    public class Admin
    {
        internal const string ActiveXGuid = "124B0FB8-DF1E-46b0-97B1-FD698C35C497";
        internal const uint CIS_E_ADMIN_CORE_FAILED_INSTANCE_NOT_FOUND = 0xc0c02537;
        internal const uint CIS_E_ADMIN_TRACKED_MSG_NOT_SUSPENDED = 0x80040e14;
        internal const uint CIS_E_ADMIN_TRACKED_MSG_PURGED = 0xc0c025b5;
        private const string ErrTblFooter = "</TABLE>";
        private const string ErrTblHeader = "<TABLE id=\"ErrMsgs\" cellSpacing=\"1\" cellPadding=\"1\" border=\"0\">";
        private const string ErrTblRow = "<TR><TD>{0}</TD></TR>";

        public Admin()
        {
            //new LockDownUnsafeTypes();
        }

        public object CreateServiceInstanceGroup(string sDtaServer, string sDtaDB, string sWmiServer)
        {
            string str = this.DecodeFromUrl(sDtaServer);
            string str2 = this.DecodeFromUrl(sDtaDB);
            string str3 = this.DecodeFromUrl(sWmiServer);
            ConfigurationManager.GetSection("system.diagnostics");
            return new SvcInstList(str, str2, str3);
        }

        private string DecodeFromUrl(string val)
        {
            return HttpUtility.UrlDecode(val);
        }

        private string EncodeForUrl(string val)
        {
            return HttpUtility.UrlEncodeUnicode(val);
        }

        internal static string FixWMIPath(string path)
        {
            return path.Replace(@"\", @"\\");
        }

        private void getAppGroupMsgBoxInfo(out string AppType, out string GroupName, out string MsgBoxSrv, out string MsgBoxDB, string DTASrv, string DtaDB, string SvcInstID)
        {
            SqlConnection selectConnection = new SqlConnection(string.Format(CultureInfo.InvariantCulture, "server='{0}';database='{1}';Trusted_Connection=yes;Pooling=false;Connect Timeout={2};", new object[] { DTASrv, DtaDB, Preferences.ConnectionTimeout }));
            try
            {
                SqlDataAdapter adapter = new SqlDataAdapter("dtasp_GetSvcInstMsgBoxInfo", selectConnection);
                adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
                adapter.SelectCommand.Parameters.Add("@instids", SqlDbType.NVarChar, 0xbb8).Value = "N'" + SvcInstID + "'";
                DataSet dataSet = new DataSet();
                dataSet.Locale = CultureInfo.InvariantCulture;
                adapter.Fill(dataSet, "Temp");
                DataTable table = dataSet.Tables["Temp"];
                table.Locale = CultureInfo.InvariantCulture;
                if (table.Rows.Count == 0)
                {
                    throw new ApplicationException();
                }
                GroupName = table.Rows[0]["strGroupName"].ToString();
                AppType = table.Rows[0]["strHostName"].ToString();
                MsgBoxSrv = table.Rows[0]["strDBServer"].ToString();
                MsgBoxDB = table.Rows[0]["strDBName"].ToString();
            }
            catch
            {
                GroupName = "";
                AppType = "";
                MsgBoxSrv = "";
                MsgBoxDB = "";
            }
            finally
            {
                BrmaDbUtil.CloseConnection(ref selectConnection);
            }
        }

        private TrackedMessageInfo[] getMessageList(string DTASrv, string DtaDB, string SvcInstID, string ActivityID)
        {
            string str;
            string str2;
            string str3;
            string str4;
            int num;
            int num2;
            int num3;
            int num4;
            BizTalkDBVersion version = new BizTalkDBVersion();
            version.PoolDbConnection = false;
            version.QueryVersionInfo(DTASrv, DtaDB, "Tracking DB", out str, out str2, out str3, out str4);
            version.BreakdownVersion(str, out num, out num2, out num3, out num4);
            string selectConnectionString = string.Format(CultureInfo.InvariantCulture, "server='{0}';database='{1}';Trusted_Connection=yes;Pooling=false;Connect Timeout={2};", new object[] { DTASrv, DtaDB, Preferences.ConnectionTimeout });
            SqlDataAdapter adapter = new SqlDataAdapter("dtasp_GetServiceInstanceMessages", selectConnectionString);
            adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
            adapter.SelectCommand.Parameters.Add("@uidServiceInstanceId", SqlDbType.UniqueIdentifier, 0x10).Value = new Guid(SvcInstID);
            if ((num2 > 2) || (num4 > 0))
            {
                if ((ActivityID == null) || (ActivityID == ""))
                {
                    adapter.SelectCommand.Parameters.Add("@uidActivityId", SqlDbType.UniqueIdentifier, 0x10).Value = DBNull.Value;
                }
                else
                {
                    adapter.SelectCommand.Parameters.Add("@uidActivityId", SqlDbType.UniqueIdentifier, 0x10).Value = new Guid(ActivityID);
                }
            }
            DataTable dataTable = new DataTable();
            dataTable.Locale = CultureInfo.InvariantCulture;
            adapter.Fill(dataTable);
            int count = dataTable.Rows.Count;
            TrackedMessageInfo[] infoArray = new TrackedMessageInfo[count];
            for (int i = 0; i < count; i++)
            {
                infoArray[i].SvcGUID = SvcInstID;
                infoArray[i].MessageGUID = dataTable.Rows[i][1].ToString();
                if (dataTable.Rows[i].IsNull(2))
                {
                    infoArray[i].MessageSize = -1L;
                }
                else
                {
                    try
                    {
                        infoArray[i].MessageSize = long.Parse(dataTable.Rows[i][2].ToString());
                    }
                    catch
                    {
                        infoArray[i].MessageSize = 0L;
                    }
                }
            }
            return infoArray;
        }

        [ComRegisterFunction]
        private static void RegisterServer(System.Type t)
        {
            ComCategoryHelper.RegisterImplementedCategory("124B0FB8-DF1E-46b0-97B1-FD698C35C497", ComCategoryHelper.CatId_SafeForScripting);
        }

        public TrackedInstance SaveAllMessagesToFile(string dtaServer, string dtaDB, string wmiServer, 
                                                    string mgmtDBServer, string mgmtDB,
                                                    string serviceInstanceID, string activityID, 
                                                    string dataType)
        {
            return SaveAllMessagesToFile(dtaServer, dtaDB, wmiServer, mgmtDBServer, mgmtDB, serviceInstanceID, activityID, dataType, null);
        }

        public TrackedInstance SaveAllMessagesToFile(string dtaServer, string dtaDB, string wmiServer,
                                                    string mgmtDBServer, string mgmtDB,
                                                    string serviceInstanceID, string activityID,
                                                    string dataType, string outputFolderFullPath)
        {
            TrackedInstance instance = new TrackedInstance(serviceInstanceID, activityID);
            try
            {
                Cursor.Current = Cursors.WaitCursor;

                dtaServer = this.DecodeFromUrl(dtaServer);
                dtaDB = this.DecodeFromUrl(dtaDB);
                wmiServer = this.DecodeFromUrl(wmiServer);
                mgmtDBServer = this.DecodeFromUrl(mgmtDBServer);
                mgmtDB = this.DecodeFromUrl(mgmtDB);
                serviceInstanceID = this.DecodeFromUrl(serviceInstanceID);
                activityID = this.DecodeFromUrl(activityID);

                if (!string.IsNullOrEmpty(serviceInstanceID))
                {
                    new Guid(serviceInstanceID);
                }

                string appType = null;
                string groupName = null;
                string msgBoxSrv = null;
                string msgBoxDB = null;
                this.getAppGroupMsgBoxInfo(out appType, out groupName, out msgBoxSrv, out msgBoxDB, dtaServer, dtaDB, serviceInstanceID);
                if (dataType != "1")
                {
                    mgmtDBServer = string.Empty;
                    mgmtDB = string.Empty;
                    msgBoxDB = string.Empty;
                    msgBoxSrv = string.Empty;
                }
                TrackedMessageInfo[] msgList = this.getMessageList(dtaServer, dtaDB, serviceInstanceID, activityID);
                if (msgList.Length == 0)
                {
                    //ErrorDlg.ShowWarning(SharedRes.NavCtrl.GetString("wrn_CouldNotFindAnyMessageFlowRecordsWhenSavingAllMsgBodies"));
                    instance.Status = SharedRes.NavCtrl.GetString("wrn_CouldNotFindAnyMessageFlowRecordsWhenSavingAllMsgBodies");
                    return instance;
                }
                for (int i = 0; i < msgList.Length; i++)
                {
                    msgList[i].MessageBoxName = msgBoxDB;
                    msgList[i].MessageBoxSrv = msgBoxSrv;
                    msgList[i].GroupName = groupName;
                    msgList[i].Host = appType;
                }
                //str13 = SaveMessageArrayToFile(msgList, wmiSrv, mgmtDBSrv, mgmtDB, dTASrv, dtaDB, false, outputFolderFullPath);
                instance.TrackedMessages = SaveMessageArrayToFile(msgList, wmiServer, mgmtDBServer, mgmtDB, dtaServer, dtaDB, false, outputFolderFullPath);
            }
            catch (Exception exception)
            {
                Exception exception2 = new Exception(ExceptionMessageProvider.GetExceptionErrorMessage(exception), exception);
                if ((exception.Message != null) && (string.Compare(exception2.Message, exception.Message, StringComparison.Ordinal) == 0))
                {
                    throw exception;
                }
                throw exception2;
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
            //return str13;
            return instance;
        }

        internal static List<TrackedMessage> SaveMessageArrayToFile(TrackedMessageInfo[] msgList, string WmiSrv, string MgmtDBSrv, string MgmtDB, string sDtaSvr, string sDtaDB, bool bSaveFromMsgBoxOnly)
        {
            return SaveMessageArrayToFile(msgList, WmiSrv, MgmtDBSrv, MgmtDB, sDtaSvr, sDtaDB, bSaveFromMsgBoxOnly, null);
        }

        internal static List<TrackedMessage> SaveMessageArrayToFile(TrackedMessageInfo[] msgList, string WmiSrv, string MgmtDBSrv, string MgmtDB, string sDtaSvr, string sDtaDB, bool bSaveFromMsgBoxOnly, string outputFolderFullPath)
        {
            /*if (msgList.Length > 0)
            {
                outputFolderFullPath = new DirBrowser().RequestFolderLocationWithChecks();
            }*/
            if (outputFolderFullPath != null)
            {
                List<TrackedMessage> statuses = new List<TrackedMessage>();

                string str3 = "<TABLE id=\"SavedMsgs\" cellSpacing=\"1\" cellPadding=\"1\" border=\"1\">";
                string str4 = "</TABLE>";
                string format = "<TR><TD>{0}</TD><TD>{1}</TD><TD>{2}</TD></TR>";
                string str6 = SharedRes.NavCtrl.GetString("adm_SvcInstID");
                string str7 = SharedRes.NavCtrl.GetString("adm_MsgInstID");
                string str8 = SharedRes.NavCtrl.GetString("adm_SaveMsgStatus");
                string str9 = SharedRes.NavCtrl.GetString("adm_Saved");
                string str10 = SharedRes.NavCtrl.GetString("adm_NotAvail");
                SharedRes.NavCtrl.GetString("adm_NoBody");
                string strError = "";
                string str2 = str3;
                str2 = str2 + string.Format(CultureInfo.CurrentCulture, format, new object[] { str6, str7, str8 });

                for (int i = 0; i < msgList.Length; i++)
                {
                    long messageSize = msgList[i].MessageSize;
                    string messageGUID = msgList[i].MessageGUID;

                    if (!messageGUID.StartsWith("{", StringComparison.Ordinal))
                    {
                        messageGUID = "{" + messageGUID + "}";
                    }

                    string svcGUID = msgList[i].SvcGUID;

                    if (!svcGUID.StartsWith("{", StringComparison.Ordinal))
                    {
                        svcGUID = "{" + svcGUID + "}";
                    }
                    if (saveMsgBodyToFile(msgList[i].MessageBoxSrv, msgList[i].MessageBoxName, WmiSrv, MgmtDBSrv, MgmtDB, messageGUID, svcGUID, outputFolderFullPath, msgList[i].Host, msgList[i].GroupName, sDtaSvr, sDtaDB, out strError, bSaveFromMsgBoxOnly))
                    {
                        if ((strError == null) || (strError.Length == 0))
                        {
                            strError = str9;
                        }
                    }
                    else if ((((msgList.Length > (i + 1)) && (string.Compare(msgList[i + 1].MessageGUID, msgList[i].MessageGUID, StringComparison.OrdinalIgnoreCase) != 0)) || (msgList.Length <= (i + 1))) && ((strError == null) || (strError.Length == 0)))
                    {
                        strError = str10;
                    }
                    if (((msgList.Length > (i + 1)) && (string.Compare(msgList[i + 1].MessageGUID, msgList[i].MessageGUID, StringComparison.OrdinalIgnoreCase) != 0)) || (msgList.Length <= (i + 1)))
                    {
                        str2 = str2 + string.Format(CultureInfo.CurrentCulture, format, new object[] { HttpUtility.HtmlEncode(msgList[i].SvcGUID), HttpUtility.HtmlEncode(messageGUID), strError });

                        TrackedMessage status = new TrackedMessage();
                        status.MessageInstanceId = msgList[i].MessageGUID;
                        status.Size = msgList[i].MessageSize;
                        status.Status = strError;
                        statuses.Add(status);
                    }

                }
                return statuses;
            }
            return null;
        }

        private static bool saveMsgBodyToFile(string MsgBoxSrv, string MsgBoxDB, string WmiServer, string MgmtDBServer, string MgmtDB, string MsgInstID, string SvcInstGUID, string OutputFolderFullPath, string AppType, string GroupName, string DtaSrv, string DtaDb, out string strError, bool bSaveFromMsgBoxOnly)
        {
            ManagementPath path;
            ManagementObject obj2;
            ManagementBaseObject methodParameters;
            string str = string.Format(CultureInfo.InvariantCulture, @"\ROOT\MicrosoftBizTalkServer", new object[0]);
            bool flag = false;
            strError = null;
            SaveAllMessagesErrorDetails details = new SaveAllMessagesErrorDetails();
            ManagementScope scope = new ManagementScope(str);
            try
            {
                scope.Connect();
                flag = true;
            }
            catch (Exception exception)
            {
                Trace.Tracer.TraceMessage(4, "BTSHATAPP: Exception {0} at {1}", new object[] { exception.Message, exception.StackTrace });
                flag = false;
                string str2 = ExceptionMessageProvider.GetExceptionErrorMessage(exception) + ". \n" + ExceptionMessageProvider.ReadErrorMessageFromResources("err_MakeSureWMIisRunning");
                details.DtaResults.HResult = uint.MaxValue;
                details.DtaResults.ErrorMessage = str2;
                details.MsgBoxResults.HResult = uint.MaxValue;
                details.MsgBoxResults.ErrorMessage = str2;
                details.SuspendedQResults.HResult = uint.MaxValue;
                details.SuspendedQResults.ErrorMessage = str2;
            }
            strError = string.Empty;
            if (((flag && !bSaveFromMsgBoxOnly) && ((DtaSrv != null) && (DtaDb != null))) && ((DtaSrv.Length != 0) && (DtaDb.Length != 0)))
            {
                try
                {
                    string format = "MSBTS_TrackedMessageInstance.SourceDBServerName=\"{0}\",SourceDBName=\"{1}\",MessageInstanceID=\"{2}\"";
                    path = new ManagementPath(FixWMIPath(string.Format(CultureInfo.InvariantCulture, format, new object[] { DtaSrv, DtaDb, MsgInstID })));
                    obj2 = new ManagementObject(scope, path, null);
                    string methodName = "SaveToFile";
                    methodParameters = obj2.GetMethodParameters(methodName);
                    methodParameters["OutputFolderFullPath"] = OutputFolderFullPath;
                    obj2.InvokeMethod(methodName, methodParameters, null);
                    return true;
                }
                catch (COMException exception2)
                {
                    details.DtaResults.HResult = (uint)exception2.ErrorCode;
                    details.DtaResults.ErrorMessage = exception2.Message;
                }
                catch (ManagementException exception3)
                {
                    details.DtaResults.HResult = (uint)exception3.ErrorCode;
                    details.DtaResults.ErrorMessage = exception3.Message;
                }
                catch (Exception exception4)
                {
                    details.DtaResults.HResult = uint.MaxValue;
                    details.DtaResults.ErrorMessage = ExceptionMessageProvider.GetExceptionErrorMessage(exception4);
                }
            }
            strError = string.Empty;
            if (((flag && (MgmtDB != null)) && ((MgmtDBServer != null) && (MgmtDB.Length != 0))) && (MgmtDBServer.Length != 0))
            {
                try
                {
                    string str7 = "MSBTS_MessageInstance.MessageInstanceID=\"{0}\",ServiceInstanceID=\"{1}\",MgmtDbNameOverride=\"{2}\",MgmtDbServerOverride=\"{3}\"";
                    path = new ManagementPath(FixWMIPath(string.Format(CultureInfo.InvariantCulture, str7, new object[] { MsgInstID, SvcInstGUID, MgmtDB, MgmtDBServer })));
                    obj2 = new ManagementObject(scope, path, null);
                    string str10 = "SaveToFile";
                    methodParameters = obj2.GetMethodParameters(str10);
                    methodParameters["OutputFolderFullPath"] = OutputFolderFullPath;
                    obj2.InvokeMethod(str10, methodParameters, null);
                    return true;
                }
                catch (COMException exception5)
                {
                    Trace.Tracer.TraceMessage(4, "BTSHATAPP: Exception {0} at {1}", new object[] { exception5.Message, exception5.StackTrace });
                    details.SuspendedQResults.HResult = (uint)exception5.ErrorCode;
                    details.SuspendedQResults.ErrorMessage = exception5.Message;
                }
                catch (ManagementException exception6)
                {
                    Trace.Tracer.TraceMessage(4, "BTSHATAPP: Exception {0} at {1}", new object[] { exception6.Message, exception6.StackTrace });
                    details.SuspendedQResults.HResult = (uint)exception6.ErrorCode;
                    details.SuspendedQResults.ErrorMessage = exception6.Message;
                }
                catch (Exception exception7)
                {
                    Trace.Tracer.TraceMessage(4, "BTSHATAPP: Exception {0} at {1}", new object[] { exception7.Message, exception7.StackTrace });
                    details.SuspendedQResults.HResult = uint.MaxValue;
                    details.SuspendedQResults.ErrorMessage = ExceptionMessageProvider.GetExceptionErrorMessage(exception7);
                }
            }
            strError = string.Empty;
            if (((flag && !bSaveFromMsgBoxOnly) && ((MsgBoxSrv != null) && (MsgBoxDB != null))) && ((MsgBoxSrv.Length != 0) && (MsgBoxDB.Length != 0)))
            {
                try
                {
                    string str11 = "MSBTS_TrackedMessageInstance2.SourceDBServerName=\"\",SourceDBName=\"\",MessageInstanceID=\"{0}\",MgmtDbNameOverride=\"{1}\",MgmtDbServerOverride=\"{2}\"";
                    path = new ManagementPath(FixWMIPath(string.Format(CultureInfo.InvariantCulture, str11, new object[] { MsgInstID, Preferences.MgmtDBName, Preferences.MgmtDBServer })));
                    obj2 = new ManagementObject(scope, path, null);
                    string str14 = "SaveToFile";
                    methodParameters = obj2.GetMethodParameters(str14);
                    methodParameters["OutputFolderFullPath"] = OutputFolderFullPath;
                    obj2.InvokeMethod(str14, methodParameters, null);
                    return true;
                }
                catch (COMException exception8)
                {
                    Trace.Tracer.TraceMessage(4, "BTSHATAPP: Exception {0} at {1}", new object[] { exception8.Message, exception8.StackTrace });
                    details.MsgBoxResults.HResult = (uint)exception8.ErrorCode;
                    details.MsgBoxResults.ErrorMessage = exception8.Message;
                }
                catch (ManagementException exception9)
                {
                    Trace.Tracer.TraceMessage(4, "BTSHATAPP: Exception {0} at {1}", new object[] { exception9.Message, exception9.StackTrace });
                    details.MsgBoxResults.HResult = (uint)exception9.ErrorCode;
                    details.MsgBoxResults.ErrorMessage = exception9.Message;
                }
                catch (Exception exception10)
                {
                    Trace.Tracer.TraceMessage(4, "BTSHATAPP: Exception {0} at {1}", new object[] { exception10.Message, exception10.StackTrace });
                    details.MsgBoxResults.HResult = uint.MaxValue;
                    details.MsgBoxResults.ErrorMessage = ExceptionMessageProvider.GetExceptionErrorMessage(exception10);
                }
            }
            strError = string.Empty;
            if (((0xc0c02537 == details.DtaResults.HResult) && (0xc0c02537 == details.SuspendedQResults.HResult)) && (0xc0c02537 == details.MsgBoxResults.HResult))
            {
                strError = SharedRes.NavCtrl.GetString("adm_SaveAllMessagesCommonError");
            }
            else
            {
                string str15;
                ArrayList list = new ArrayList();
                if ((details.DtaResults.HResult != 0) && (0xc0c02537 != details.DtaResults.HResult))
                {
                    str15 = SharedRes.NavCtrl.GetString("adm_SaveAllMessage_FromTrackingDb") + details.DtaResults.ErrorMessage;
                    list.Add(str15);
                }
                if ((details.SuspendedQResults.HResult != 0) && (0xc0c02537 != details.SuspendedQResults.HResult))
                {
                    str15 = SharedRes.NavCtrl.GetString("adm_SaveAllMessage_FromSuspendedQ");
                    if (0xc0c02537 == details.SuspendedQResults.HResult)
                    {
                        str15 = str15 + SharedRes.NavCtrl.GetString("CIS_E_ADMIN_CORE_FAILED_INSTANCE_NOT_FOUND");
                    }
                    else
                    {
                        str15 = str15 + details.SuspendedQResults.ErrorMessage;
                    }
                    list.Add(str15);
                }
                if ((details.MsgBoxResults.HResult != 0) && (0xc0c02537 != details.MsgBoxResults.HResult))
                {
                    str15 = SharedRes.NavCtrl.GetString("adm_SaveAllMessage_FromMessageBox") + details.MsgBoxResults.ErrorMessage;
                    list.Add(str15);
                }
                strError = string.Empty;
                if (list.Count > 0)
                {
                    strError = "<TABLE id=\"ErrMsgs\" cellSpacing=\"1\" cellPadding=\"1\" border=\"0\">";
                    for (int i = 0; i < list.Count; i++)
                    {
                        strError = strError + string.Format("<TR><TD>{0}</TD></TR>", list[i].ToString());
                    }
                    strError = strError + "</TABLE>";
                }
            }
            return false;
        }

        [ComUnregisterFunction]
        private static void UnregisterServer(System.Type t)
        {
            ComCategoryHelper.UnregisterImplementedCategory("124B0FB8-DF1E-46b0-97B1-FD698C35C497", ComCategoryHelper.CatId_SafeForScripting);
        }


        [StructLayout(LayoutKind.Sequential)]
        public struct ErrorDetails
        {
            public string ErrorMessage;
            public uint HResult;
        }

        public class SaveAllMessagesErrorDetails
        {
            public Admin.ErrorDetails DtaResults;
            public Admin.ErrorDetails MsgBoxResults;
            public Admin.ErrorDetails SuspendedQResults;

            public SaveAllMessagesErrorDetails()
            {
                this.DtaResults.ErrorMessage = string.Empty;
                this.DtaResults.HResult = 0;
                this.SuspendedQResults.ErrorMessage = string.Empty;
                this.SuspendedQResults.HResult = 0;
                this.MsgBoxResults.ErrorMessage = string.Empty;
                this.MsgBoxResults.HResult = 0;
            }
        }
    }
}

